package cn.elwy.rcp.ui.explorer.project;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.resources.ICommand;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.handlers.HandlerUtil;

public class ProjectUtil {

  private static final String CNF_ID = "cn.elwy.rcp.ui.navigator.ProjectExplorer";

  public static boolean isExistProject(String projectName) {
    IWorkspace workspace = ResourcesPlugin.getWorkspace();
    IWorkspaceRoot root = workspace.getRoot();
    IProject project = root.getProject(projectName);
    return project.exists();
  }

  public static IProject createProject(String projectName, IPath location) throws CoreException {
    IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
    return createProject(project, location);
  }

  public static IProject createProject(IProject project, IPath location) throws CoreException {
    NullProgressMonitor monitor = new NullProgressMonitor();
    if (!project.exists()) {
      if (!Platform.getLocation().equals(location)) {
        IProjectDescription desc = project.getWorkspace().newProjectDescription(project.getName());
        desc.setLocation(location);
        project.create(desc, monitor);
      } else {
        project.create(monitor);
      }
    }
    if (!project.isOpen()) {
      project.open(monitor);
    }

    IProjectDescription description = project.getDescription();
    addNature2Project(description, new String[] { CNFProjectNature.ID }, null);

    project.setDescription(description, monitor);

    return project;
  }

  public static void addNature2Project(IProjectDescription description, String[] natureIds, IProgressMonitor monitor)
      throws CoreException {
    String[] prevNatures = description.getNatureIds();
    String[] newNatures = new String[prevNatures.length + natureIds.length];
    System.arraycopy(prevNatures, 0, newNatures, 0, prevNatures.length);
    for (int i = prevNatures.length; i < newNatures.length; i++) {
      newNatures[i] = natureIds[i - prevNatures.length];
    }
    description.setNatureIds(newNatures);
  }

  public static void addBuilderToProject(IProjectDescription description, String[] builderIds, IProgressMonitor monitor)
      throws CoreException {
    ICommand[] buildSpec = description.getBuildSpec();
    ICommand[] newBuilders = new ICommand[buildSpec.length + builderIds.length];
    System.arraycopy(buildSpec, 0, newBuilders, 0, buildSpec.length);
    for (int i = buildSpec.length; i < newBuilders.length; i++) {
      ICommand command = description.newCommand();
      command.setBuilderName(builderIds[i - buildSpec.length]);
      newBuilders[i] = command;
    }
    description.setBuildSpec(newBuilders);
  }

  public static void removeBuilderFromProject(IProjectDescription description, String[] builderIds,
      IProgressMonitor monitor) {
    ICommand[] buildSpec = description.getBuildSpec();
    List<ICommand> newBuilders = new ArrayList<ICommand>();
    for (ICommand command : buildSpec) {
      boolean find = false;
      for (String id : builderIds) {
        if (command.getBuilderName().equals(id)) {
          find = true;
          break;
        }
      }
      if (!find) {
        newBuilders.add(command);
      }
    }
    description.setBuildSpec(newBuilders.toArray(new ICommand[0]));
  }

  /**
   * 获取当前选中的工程
   * 
   * @param event
   * @return
   */
  public static IProject getSelectionProject(ExecutionEvent event) {
    IResource selection = getSelection(event);
    if (selection != null) {
      return selection.getProject();
    }
    return null;
  }

  /**
   * 获取当前选中的资源
   * 
   * @param event
   * @return
   */
  public static IResource getSelection(ExecutionEvent event) {
    IResource selectionElement = null;
    if (event == null) {
      selectionElement = getSelectionElement(getSelection());
    } else {
      ISelection iSelection = HandlerUtil.getActiveWorkbenchWindow(event).getActivePage().getSelection();
      selectionElement = getSelectionElement(iSelection);
      if (selectionElement == null) {
        selectionElement = getSelectionElement(getSelection());
      }
    }
    return selectionElement;
  }

  /**
   * 获取当前选中的工程
   * 
   * @return
   */
  private static ISelection getSelection() {
    IViewPart viewPart = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().findView(CNF_ID);
    ISelection iSelection = viewPart.getSite().getSelectionProvider().getSelection();
    return iSelection;
  }

  private static IResource getSelectionElement(ISelection iSelection) {
    if (iSelection != null && iSelection instanceof IStructuredSelection) {
      IStructuredSelection selection = (IStructuredSelection) iSelection;
      if (selection.getFirstElement() instanceof IResource) {
        return (IResource) selection.getFirstElement();
      }
    }
    return null;
  }

}
